﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using FourthWallProject.GameObjects.GameComponents;

namespace FourthWallProject.GameObjects.Solids
{
    abstract class PhysicsEnabledGameObject : GameObject
    {
        public PhysicsEnabledGameObject(Texture2D texture, Rectangle rectangle, Color color, Game game)
            : base(texture, rectangle, color, game)
        {
            CurrentSpeedY = 0;
            CurrentSpeedX = 0;
            RealHeight = rectangle.Height;
            RealWidth = rectangle.Width;
            GravityForce = 0.3f;
            HorizontalForce = 0.4f;
            CurrentFriction = 0.8f;
            LastPosition = this.Position;
        }


        float RealHeight;
        float RealWidth;

        public float CurrentSpeedY;
        public float CurrentSpeedX;

        const float MaxSpeedX = 10;
        const float MaxSpeedY = 15;

        float GravityForce;
        float HorizontalForce;

        float CurrentFriction;

        bool isOnGround = false;

        public Vector2 LastPosition { get; set; }

        public float SecondX
        {
            get;
            set;
        }

        public float SecondY
        { get; set; }

        public float SecondWidth { get; set; }

        public float SecondHeight { get; set; }

        public Rectangle SecondRectangle
        {
            get { return new Rectangle((int)SecondX, (int)SecondY, (int)this.SecondWidth, (int)this.SecondHeight); }
        }

        public Rectangle SecondRectangleWithCameraOffset
        {
            get { return new Rectangle((int)SecondX + GameCamera.X, (int)SecondY + GameCamera.Y, (int)this.SecondWidth, (int)this.SecondHeight); }
        }

        public override void Draw(GameTime gameTime)
        {
            ScreenManager.SpriteBatch.Begin();
            ScreenManager.SpriteBatch.Draw(this.Texture, SecondRectangleWithCameraOffset, this.Color);
            ScreenManager.SpriteBatch.End();
            base.Draw(gameTime);
        }

        public override void Update(GameTime gameTime)
        {
            DoPhysics();

            if (GameCamera.isFollowing)
            {
                Height = RealHeight;
                Width = RealWidth;
                SecondWidth = 0;
                SecondHeight = 0;
                SecondX = 0;
                SecondY = 0;
            }
            base.Update(gameTime);
        }



        public void IsIntersected()
        {
            if (CurrentSpeedY < 0)
                CurrentSpeedY = GravityForce;
            else
            {
                CurrentSpeedY = 0;
                isOnGround = true;
            }

            this.Position = LastPosition;
        }

        public void Jump()
        {
            if (isOnGround)
            {
                CurrentSpeedY = -10f;
                isOnGround = false;
            }
        }

        private float XRelativeToCamera
        {
            get{return (X + GameCamera.X);}
        }

        private float YRelativeToCamera
        {
            get { return (Y + GameCamera.Y); }
        }
        private float SecondYRelativeToCamera
        {
            get { return (SecondY + GameCamera.Y); }
        }

        internal void DoPhysics()
        {
            LastPosition = this.Position;

            if (!isOnGround)
            { 
                if(this.CurrentSpeedY < MaxSpeedY)
                    this.CurrentSpeedY += this.GravityForce;
                this.Y += CurrentSpeedY;
            }

            var oldCurrentSpeedX = CurrentSpeedX;

            this.X += CurrentSpeedX;

            //if (YRelativeToCamera < 0 && GameCamera.isStatic)
            //{
            //    var lastHeight = Height;
            //    Height += YRelativeToCamera;
            //    Width = RealWidth;
            //    SecondHeight = RealHeight - Height;
            //    SecondWidth = RealWidth;
            //    SecondY = GameCamera.WindowHeight - GameCamera.Y - SecondHeight;
            //    SecondX = X;
            //    Y -= YRelativeToCamera;
            //    if (Height <= 0)
            //    {
            //        X = SecondX;
            //        Y = SecondY;
            //        Width = SecondWidth;
            //        Height = SecondHeight;
            //        SecondHeight = 0;
            //        SecondWidth = 0;
            //        SecondX = 0;
            //        SecondY = 0;
            //    }
            //}
            //if (YRelativeToCamera + Height > GameCamera.WindowHeight)
            //{
            //    var lastHeight = Height;
            //    Height -= YRelativeToCamera + Height;
            //    Width = RealWidth;
                
            //}

            if (XRelativeToCamera + Width >  GameCamera.WindowWidth)
            {
                X = -GameCamera.X;
            }
            if (XRelativeToCamera < 0)
            { 
                X = -GameCamera.X + GameCamera.WindowWidth - this.Width;
            }
            if (YRelativeToCamera + Height > GameCamera.WindowHeight)
            {
                Y = -GameCamera.Y;
            }
            if (YRelativeToCamera < 0)
            {
                Y = -GameCamera.Y + GameCamera.WindowHeight - this.Height;
            }

            if (CurrentSpeedX > 0)
            {
                CurrentSpeedX -= HorizontalForce * CurrentFriction;
                if (CurrentSpeedX < 0)
                    CurrentSpeedX = 0;

            }
            else if (CurrentSpeedX < 0)
            {
                CurrentSpeedX += HorizontalForce * CurrentFriction;
                if (CurrentSpeedX > 0)
                    CurrentSpeedX = 0;
            }
            //if (oldCurrentSpeedX > CurrentSpeedX && right)
            //    this.CurrentSpeedX = 0;
        }

        internal void MoveLeft()
        {
            if (CurrentSpeedX > MaxSpeedX * -1)
            {
                CurrentSpeedX -= HorizontalForce;
            }
        }

        internal void MoveRight()
        {
            if (CurrentSpeedX < MaxSpeedX)
            {
                CurrentSpeedX += HorizontalForce;
            }
        }

        internal void DoFalling()
        {
            if (isOnGround)
            { 
                CurrentSpeedY = GravityForce;
                isOnGround = false;
            }
        }
    }
}